using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using GameFramework;
using UnityEditor;
using UnityGameFramework.Runtime;

namespace StarForce.Editor
{
    internal class OpcodeInfo
    {
        public string Name;
        public int Opcode;
    }
    
       public class Proto2CSEditor : EditorWindow
    {
        private const string protoPath = "Assets/Proto/";
        private const string clientMessagePath = "Assets/GameMain/Scripts/Network/ProtoGenerator/";
//        private static readonly char[] splitChars = { ' ', '\t' };
        private static readonly List<OpcodeInfo> msgOpcode = new List<OpcodeInfo>();

        [MenuItem("Star Force/Proto2CS")]
        public static void AllProto2CS()
        {
            string rootDir = Environment.CurrentDirectory;
            string protoDir = Path.Combine(rootDir, "Assets/Proto/");

            string protoc;
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                protoc =Path.Combine(protoDir, "protoc.exe");
            }
            else
            {
                protoc = Path.Combine(protoDir, "protoc");
            }

//            string outerMessageCodePath =Path.Combine(rootDir, "Assets", "Scripts", "Libraries", "ET", "Module", "Message/");
//
//            string hotfixMessageCodePath = Path.Combine(rootDir, "Assets", "Scripts", "Hotfix", "ETNetwork", "Module", "Message/");

            string argument1 = $"--csharp_out=\"{clientMessagePath}\" --proto_path=\"{protoDir}\" OuterMessage.proto";
            string argument2 = $"--csharp_out=\"{clientMessagePath}\" --proto_path=\"{protoDir}\" HotfixMessage.proto";

            Run(protoc, argument1, waitExit: true);
            Run(protoc, argument2, waitExit: true);

            // InnerMessage.proto生成cs代码
//            InnerProto2CS.Proto2CS();

//            msgOpcode.Clear();
//            Proto2CS("StarForce", "OuterMessage.proto", clientMessagePath, "OuterOpcode", 100);

            UnityEngine.Debug.Log("proto2cs succeed!");

            AssetDatabase.Refresh();
        }
        
        public static Process Run(string exe, string arguments, string workingDirectory = ".", bool waitExit = false)
        {
            try
            {
                bool redirectStandardOutput = true;
                bool redirectStandardError = true;
                bool useShellExecute = false;
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    redirectStandardOutput = false;
                    redirectStandardError = false;
                    useShellExecute = true;
                }

                if (waitExit)
                {
                    redirectStandardOutput = true;
                    redirectStandardError = true;
                    useShellExecute = false;
                }
                
                ProcessStartInfo info = new ProcessStartInfo
                {
                    FileName = exe,
                    Arguments = arguments,
                    CreateNoWindow = true,
                    UseShellExecute = useShellExecute,
                    WorkingDirectory = workingDirectory,
                    RedirectStandardOutput = redirectStandardOutput,
                    RedirectStandardError = redirectStandardError,
                };
                
                Process process = Process.Start(info);

                if (waitExit)
                {
                    process.WaitForExit();
                    if (process.ExitCode != 0)
                    {
                        throw new Exception($"{process.StandardOutput.ReadToEnd()} {process.StandardError.ReadToEnd()}");
                    }
                }

                return process;
            }
            catch (Exception e)
            {
                throw new Exception($"dir: {Path.GetFullPath(workingDirectory)}, command: {exe} {arguments}", e);
            }
        }
    }
}